#ifndef __ARBOL_BINARIO_H__
#define __ARBOL_BINARIO_H__

#include "nodo_arbol_binario.h"

template <class T> class ArbolBinario {

private:
	NodoArbolBinario<T>* raiz;

public:
	/**
	* Postcondiciones: El arbol queda creado vacio.
	*/
	ArbolBinario(){
		this->setRaiz(0);
	}

	/**
	* Postcondiciones: El arbol queda eliminado junto con los
	*                  datos que contenia.
	*/
	~ArbolBinario(){
		if(this->getRaiz() != 0){
			delete this->getRaiz();
		}
	}

	/**
	 * Postcondiciones: Se crea un arbol igual al indicado.
	 */
	ArbolBinario(const ArbolBinario<T> &otroArbol){
		if(otroArbol.raiz != 0){
			NodoArbolBinario<T> *nodo = new NodoArbolBinario<T>(*(otroArbol.raiz));
			this->raiz = nodo;
		}else{
			this->raiz = 0;
		}
	}

	/**
	 * Postcondiciones: El arbol queda igual a otroArbol.
	 */
	ArbolBinario<T>& operator=(const ArbolBinario<T> &otroArbol) {
		if(this != &otroArbol){
			if(this->raiz != 0){
				delete this->raiz;
				this->raiz = 0;
			}

			if(otroArbol.raiz != 0){
				NodoArbolBinario<T> *nodo = new NodoArbolBinario<T>(*(otroArbol.raiz));
				this->raiz = nodo;
			}
		}

		return *this;
	}


	/**
	* Postcondiciones: Retorna true si el arbol esta vacio, false
	*                  en caso contrario.
	*/
	bool estaVacio(){
		return (this->getRaiz() == 0);
	}

	/**
	* Postcondiciones: Retorna un puntero a la raiz del arbol, o NULL en
	*                  caso de que este vacio.
	*/
	NodoArbolBinario<T>* getRaiz(){
		return this->raiz;
	}

	/**
	 * Postcondiciones: Se setea el nodo indicado como raiz del arbol.
	 */
	void setRaiz(NodoArbolBinario<T>* nuevaRaiz){
		this->raiz = nuevaRaiz;
	}

};

#endif /* __ARBOL_BINARIO_H__ */
